package com.efuture.chaptersix

/* @Description:Kotlin语言out 协变学习
 * @Auther: zhaoshanshan
 * @Date: 2022/03/08/4:07 下午
 */

interface Producer<out T>{
    //fun consumer(item:T) 该行代码会报错 因为out代表只可读 不能被修改
    fun producer():T //改行代码ok 因为T可以被读取
}
open class Animal();
open class Persons():Animal()
open class Man():Persons()
open class Woman():Persons()

class ProducerClass1:Producer<Animal>{
    override fun producer(): Animal {
        println("生产Animal")
        return Animal()
    }

}
class ProducerClass2:Producer<Persons>{
    override fun producer(): Persons {
        println("生产Persons")
        return Persons()
    }

}
class ProducerClass3:Producer<Man>{
    override fun producer(): Man {
        println("生产Man")
        return Man()
    }

}
class ProducerClass4:Producer<Woman>{
    override fun producer(): Woman {
        println("生产Animal")
        return Woman()
    }

}

fun main() {

    val p1 :Producer<Animal>  = ProducerClass1()//ProducerClass1他本来就是 传递 Animal ，当然是可以的
    val p2 :Producer<Animal>  = ProducerClass2()//ProducerClass2他本来就是 传递 Humanity，居然也可以，因为out 如果没有out 会报错
    val p3 :Producer<Animal> = ProducerClass3();//ProducerClass3他本来就是 传递 Humanity，居然也可以，因为out 如果没有out 会报错
    val p4 :Producer<Animal> = ProducerClass4();//ProducerClass4他本来就是 传递 Humanity，居然也可以，因为out 如果没有out 会报错

    // 泛型默认情况下是：泛型的子类对象 不可以赋值给 泛型的父类对象
    // 泛型默认情况下是：泛型具体处的子类对象  不可以赋值给 泛型声明处的父类对象

    // out: 泛型的子类对象 可以赋值给 泛型的父类对象
    // out: 泛型具体出的子类对象 可以赋值给 泛型声明处的父类对象

    // 协变：父类 泛型声明处  可以接收   子类 泛型具体处
    // ? extends T 就相当于 KT里面的out，所以才可以 泛型子类对象 赋值给 泛型父类对象
    // out: 泛型具体出的子类对象 可以赋值给 泛型声明处的父类对象
    //List<? extends CharSequence> list2 = new ArrayList<String>();
}
    